package com.yao.mall.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.plugins.pagination.PageDTO;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.yao.mall.common.ErrorCode;
import com.yao.mall.common.UserHolder;
import com.yao.mall.config.BusinessException;
import com.yao.mall.mapper.*;
import com.yao.mall.model.dto.CategoryRequest;
import com.yao.mall.model.dto.CategorySearchRequest;
import com.yao.mall.model.entity.*;
import com.yao.mall.model.vo.*;
import com.yao.mall.service.AttrKeyService;
import com.yao.mall.service.BrandService;
import com.yao.mall.service.CategoryService;
import com.yao.mall.service.GoodsService;
import jakarta.annotation.Resource;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;

import static com.yao.mall.constant.CommonConstant.PARENT_ID;
import static com.yao.mall.constant.CommonConstant.ZERO;

/**
 * @author jiahua.yao
 * @description 针对表【address】的数据库操作Service实现
 * @date 2024-03-05 11:17:49
 */
@Service
//首页中通过分类展示的商品信息限制为5条
public class CategoryServiceImpl extends ServiceImpl<CategoryMapper, Category>
        implements CategoryService {

    @Resource
    private CategoryMapper categoryMapper;

    @Resource
    private AttrKeyMapper attrKeyMapper;

    @Resource
    private BrandMapper brandMapper;

    @Resource
    private GoodsMapper goodsMapper;

    @Resource
    private GoodsService goodsService;

    @Resource
    private BrandService brandService;

    @Resource
    private AttrKeyService attrKeyService;

    private static final String CATEGORY_ID= "category_id";

    @Override
    public List<CategoryVO> getCategory() {
        List<Category> categoryList = this.list();
        List<CategoryVO> categoryVOList = categoryList.stream()
                .filter(category -> category.getParentId() == 0)
                .map(categoryParent -> {
                    //获取子分类,源list筛选id == parentId，避免多次查询数据库
                    CategoryVO categoryVO = new CategoryVO();
                    List<SecCategoryVO> secCategoryVOList = categoryList.stream()
                            .filter(categorySon -> categoryParent.getId().equals(categorySon.getParentId()))
                            .map(secCategory -> {
                                SecCategoryVO secCategoryVO = new SecCategoryVO();
                                BeanUtils.copyProperties(secCategory, secCategoryVO);
                                return secCategoryVO;
                            }).toList();
                    BeanUtils.copyProperties(categoryParent, categoryVO);
                    categoryVO.setSecCategoryList(secCategoryVOList);
                    return categoryVO;
                }).toList();
        if (categoryVOList.isEmpty()) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "分类数据错误！");
        }
        return categoryVOList;
    }

    @Override
    public Boolean addCategory(Category category) {
        checkPower();
        Long parentId = category.getParentId();
        String name = category.getName();
        if (StringUtils.isBlank(name) || parentId == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "必填字段不能为空！");
        }
        return this.save(category);
    }

    @Override
    public List<Category> getParentName() {
        QueryWrapper<Category> categoryQueryWrapper = new QueryWrapper<>();
        categoryQueryWrapper.eq(PARENT_ID, 0);
        return categoryMapper.selectList(categoryQueryWrapper);
    }

    @Override
    public List<Category> getChildName() {
        QueryWrapper<Category> categoryQueryWrapper = new QueryWrapper<>();
        categoryQueryWrapper.ne(PARENT_ID, 0);
        return categoryMapper.selectList(categoryQueryWrapper);
    }

    @Override
    public Page<Category> getByConditions(CategorySearchRequest categorySearchRequest) {
        long pageSize = categorySearchRequest.getPageSize();
        long current = categorySearchRequest.getCurrent();
        QueryWrapper<Category> categoryQueryWrapper = new QueryWrapper<>();
        String name = categorySearchRequest.getName();
        if(StringUtils.isNotBlank(name)){
            categoryQueryWrapper.like("name",name);
        }
        return this.page(new PageDTO<>(current, pageSize), categoryQueryWrapper);
    }

    @Override
    public CategoryVO getCategoryByParentId(Integer id) {
        QueryWrapper<Category> categoryQueryWrapper = new QueryWrapper<>();
        //SELECT id,parent_id,name,pic FROM category WHERE (parent_id = ? OR id = ?) ORDER BY parent_id DESC
        categoryQueryWrapper.eq(PARENT_ID, id).or().eq("id", id).orderBy(true,true,"parent_id");
        List<Category> categoryList = categoryMapper.selectList(categoryQueryWrapper);
        return getCategoryVO(categoryList.get(0), categoryList,id);
    }


    private static void checkPower() {
        UserVO user = UserHolder.getUser();
        if (!"1".equals(user.getUserPower())) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "权限不足！");
        }
    }

    @Override
    public Boolean deleteCategory(Long id) {
        checkPower();
        //注意父分类如果关联了子分类且子分类存在，不可删除
        QueryWrapper<Category> categoryQueryWrapper = new QueryWrapper<>();
        categoryQueryWrapper.eq(PARENT_ID, id);
        Long count = categoryMapper.selectCount(categoryQueryWrapper);
        if (count > 0) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "该分类存在子分类，不可删除");
        }
        //子类有相关商品也不可以删除
        QueryWrapper<Goods> goodsQueryWrapper = new QueryWrapper<>();
        goodsQueryWrapper.eq(CATEGORY_ID,id);
        Long selectCount = goodsMapper.selectCount(goodsQueryWrapper);
        if (selectCount > 0) {
            throw new BusinessException(ErrorCode.OPERATION_ERROR, "该分类存在商品，不可删除");
        }
        return this.removeById(id);
    }

    @Override
    public Boolean updateCategory(Category category) {
        checkPower();
        String name = category.getName();
        Long parentId = category.getParentId();
        Long id = category.getId();
        if (StringUtils.isBlank(name) || parentId == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "必填字段不能为空！");
        }
        //如果修改了分类标准
        if (parentId != 0) {
            QueryWrapper<Category> categoryQueryWrapper = new QueryWrapper<>();
            categoryQueryWrapper.eq(PARENT_ID, id);
            //注意：如果把要修改父分类为子分类，需要做子分类查询判断是否可行，不可行返回可执行要求
            Long count = categoryMapper.selectCount(categoryQueryWrapper);
            if (count > 0) {
                throw new BusinessException(ErrorCode.OPERATION_ERROR, "该分类存在子分类，请删除子类后尝试修改分类级别！");
            }
        }
        //否
        return this.updateById(category);
    }

    @Override
    public BrandAndAttrKeyVO getBrandAndAttrKeyByCategory(CategoryRequest categoryRequest) {
        Long categoryId = categoryRequest.getId();
        if (categoryId == null) {
            throw new BusinessException(ErrorCode.PARAMS_ERROR);
        }
        QueryWrapper<AttrKey> attrKeyQueryWrapper = new QueryWrapper<>();
        attrKeyQueryWrapper.eq(CATEGORY_ID, categoryId);
        List<AttrKey> attrKeyList = attrKeyMapper.selectList(attrKeyQueryWrapper);
        //设置返回vo
        BrandAndAttrKeyVO brandAndAttrKeyVO = new BrandAndAttrKeyVO();
        brandAndAttrKeyVO.setAttrKeyList(attrKeyService.toAttrKeyVO(attrKeyList));
        //获取brandList
        QueryWrapper<Brand> brandQueryWrapper = new QueryWrapper<>();
        brandQueryWrapper.eq(CATEGORY_ID, categoryId);
        List<Brand> brandList = brandMapper.selectList(brandQueryWrapper);
        brandAndAttrKeyVO.setBrandList(brandService.toBrandVO(brandList));
        return brandAndAttrKeyVO;
    }

    @Override
    public List<CategoryVO> getCategoryAndGoodsVO() {
        List<Category> categoryList = this.list();
        List<CategoryVO> categoryVOList = categoryList.stream()
                .filter(category -> category.getParentId() == 0)
                //获取子分类,源list筛选id == parentId，避免多次查询数据库
                .map(categoryParent -> getCategoryVO(categoryParent, categoryList,null)).toList();
        if (categoryVOList.isEmpty()) {
            throw new BusinessException(ErrorCode.SYSTEM_ERROR, "分类数据错误！");
        }
        return categoryVOList;
    }

    @Override
    public SecCategoryVO getCategoryBySecId(Integer id) {
        //1、子类信息
        Category secCategory = this.getById(id);
        if(ZERO.equals(secCategory.getParentId())){
            throw new BusinessException(ErrorCode.PARAMS_ERROR,"分类参数错误");
        }
        //2、对应商品信息
        QueryWrapper<Goods> goodsQueryWrapper = new QueryWrapper<>();
        // 商品必须是上架的商品,1-已上架
        goodsQueryWrapper.eq(CATEGORY_ID,id).eq("spu_status", "1").last("limit 5");
        List<Goods> goods = goodsMapper.selectList(goodsQueryWrapper);
        List<GoodsBasicVO> goodsBasicVOs = goodsService.toGoodsBasicVO(goods);
        //3、父类信息
        Category category = categoryMapper.selectById(secCategory.getParentId());
        //4、存入vo返回
        SecCategoryVO secCategoryVO = new SecCategoryVO();
        BeanUtils.copyProperties(secCategory,secCategoryVO);
        secCategoryVO.setParentName(category.getName());
        secCategoryVO.setGoodsBasicListForSecCate(goodsBasicVOs);
        return secCategoryVO;
    }


    /**
     * 注意，当传id时，说明是根据parent_id直接查询子分类，商品信息存入二级分类vo中,反之直接存入一级分类中
     * @param categoryParent 父分类信息
     * @param categoryList 分类list
     * @param id 父id
     * @return categoryVO
     */
    private CategoryVO getCategoryVO(Category categoryParent, List<Category> categoryList,Integer id) {
        CategoryVO categoryVO = new CategoryVO();
        ArrayList<GoodsBasicVO> voArrayList = new ArrayList<>();
        List<SecCategoryVO> secCategoryVOList = categoryList.stream()
                .filter(categorySon -> categoryParent.getId().equals(categorySon.getParentId()))
                .map(secCategory -> {
                    SecCategoryVO secCategoryVO = new SecCategoryVO();
                    QueryWrapper<Goods> goodsQueryWrapper = new QueryWrapper<>();
                    goodsQueryWrapper.eq(CATEGORY_ID, secCategory.getId()).eq("spu_status", "1");
                    List<Goods> goodsList = goodsMapper.selectList(goodsQueryWrapper);
                    BeanUtils.copyProperties(secCategory, secCategoryVO);
                    List<GoodsBasicVO> goodsBasicVO = goodsService.toGoodsBasicVO(goodsList);
                    if(id == null) {
                        voArrayList.addAll(goodsBasicVO);
                    }else {
                        secCategoryVO.setGoodsBasicListForSecCate(goodsBasicVO);
                    }
                    return secCategoryVO;
                }).toList();
        BeanUtils.copyProperties(categoryParent, categoryVO);
        categoryVO.setSecCategoryList(secCategoryVOList);
        //在父分类上添加该子分类对应的所有商品
        if(id == null) {
            categoryVO.setGoodsBasicList(voArrayList);
        }
        return categoryVO;
    }


}




